﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using Item.Buff;

namespace Player.Fort
{
    public class Fort : MonoBehaviour
    {
        private const int FirstHP=100;
        private const float FirstHPS = 1f;

        private const string FloatFormat = "0.0";
        private const string NodePrefabPath = "Prefab/Node";
        private const int RowCount = 10, ColumnCount = 5;//行，列

        private STHexagonPosData nodePosData;
        private FortNode[] arrNode;
        public FortNode this[int x, int y]
        {
            get
            {
                if (x < 0 || x >= RowCount || y < 0 || y >= ColumnCount)
                    return null;
                var node = arrNode[x * ColumnCount + y];
                return node;
            }
        }
        public FortNode this[Vector2Int pos]=>this[pos.x,pos.y];

        public FortHP HP { get; private set; }

        private void Awake()
        {
            MyPlayer.Ins.MyFort = this;

            HP = new FortHP(FirstHP, FirstHPS);
            TextMesh hpText = transform.Find("HPText").GetComponent<TextMesh>();
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            HP.EventOnHpChange += (hp) =>
            {
                sb.Clear();
                sb.Append($"HP:{(int)hp.CurHp}/{(int)hp.MaxHp} ");
                sb.Append($"HPS:{(hp.HPS_Fixed+hp.CurHPS_Percent).ToString(FloatFormat)}/s ({(hp.HPS_Percent*100f).ToString(FloatFormat)}%) ");
                sb.Append($"Shild:{hp.Shild_Fixed.ToString(FloatFormat)} + ({(hp.Shild_Percent*100f).ToString(FloatFormat)}%)");
                hpText.text = sb.ToString();
            };
            HP.EventOnDeath += MyPlayer.Ins.Death;
            HP.MaxHp = HP.MaxHp;//用事件来刷新UI

            InitNode();
        }

        // Start is called before the first frame update
        void Start()
        {
        }

        // Update is called once per frame
        void Update()
        {

        }

        private void LateUpdate()
        {
            HP.Refresh(Time.deltaTime);
        }

        public void Reset()
        {
            for (int i = 0; i < arrNode.Length; i++)
            {
                if (arrNode[i].HaveItem)
                {
                    var item = arrNode[i].CurItem;
                    arrNode[i].CancelEquip(item);
                    //TODO 有缘再改内存池
                    Destroy(item.gameObject);
                }
            }

            HP.Reset(FirstHP, FirstHPS);
        }

        private void InitNode()
        {
            nodePosData = new STHexagonPosData(RowCount, ColumnCount, 0.25f);
            var prefab = Resources.Load<GameObject>(NodePrefabPath);
            arrNode = new FortNode[RowCount * ColumnCount];

            //TODO 位置，缩放处理，偷懒直接手动保存在场景

            for (int i = 0; i < RowCount; i++)
            {
                for (int j = 0; j < ColumnCount; j++)
                {
                    var nodeObj = Instantiate(prefab);
                    nodeObj.transform.SetParent(transform);
                    nodeObj.transform.localScale = Vector3.one * 0.25f;
                    nodeObj.transform.localPosition = nodePosData.GetPos(new Vector2Int(i, j));

                    var node = nodeObj.AddComponent<FortNode>();
                    node.vIndex = new Vector2Int(i, j);
                    arrNode[i * ColumnCount + j] = node;
                }
            }
        }

        public FortNode CheckCanEquipItem(Vector3 pos, Item.ItemBase item)
        {
            Vector2Int index = nodePosData.GetIndex(pos - transform.position);
            if (index.x >= RowCount || index.x < 0 || index.y >= ColumnCount || index.y < 0)
                return null;
            //var node=  arrNode.ToList().OrderBy((node) => (node.transform.position - pos).sqrMagnitude).ToList()[0];
            var node = arrNode[index.x * ColumnCount + index.y];

            return node;
        }

        public void AddBuff(Vector2Int index, ST_ItemBuffData[] buffDatas,int range)
        {
            Vector2Int[] arr = nodePosData.GetRoundPos(index, range);
            FortNode node;
            for (int i = 0; i < arr.Length; i++)
            {
                node = this[arr[i]];
                if (node != null)
                {
                    node.AddBuff(buffDatas);
                }
            }
        }
        public void RemoveBuff(Vector2Int index, string guid,int range)
        {
            Vector2Int[] arr = nodePosData.GetRoundPos(index, range);
            FortNode node;
            for (int i = 0; i < arr.Length; i++)
            {
                node = this[arr[i]];
                if (node != null)
                {
                    node.RemoveBuff(guid);
                }
            }
        }
    }

}